package cn.com.surker.util;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @author luotao
 * @date 2021/10/28
 */
public class ReportDateUtils {

	/**
	 * 获取报表今日日期
	 * @return
	 */
	public synchronized static String getToday() {
		Date nowDate = new Date();
		String startTime = DateUtil.convertString(nowDate, "yyyy-MM-dd") + " 08:30:00";
		if (nowDate.getTime() > DateUtil.convertDate(startTime).getTime())
			return DateUtil.convertString(nowDate, "yyyy-MM-dd");

		return DateUtil.convertString(DateUtil.convertBeforeDayDate(nowDate, 1), "yyyy-MM-dd");
	}

	/**
	 * 获取报表昨日日期
	 * @return
	 */
	public synchronized static String getYesterday() {
		Date nowDate = new Date();
		String startTime = DateUtil.convertString(nowDate, "yyyy-MM-dd") + " 08:30:00";
		if (nowDate.getTime() > DateUtil.convertDate(startTime).getTime())
			return DateUtil.convertString(DateUtil.convertBeforeDayDate(nowDate, 1), "yyyy-MM-dd");

		return DateUtil.convertString(DateUtil.convertBeforeDayDate(nowDate, 2), "yyyy-MM-dd");
	}

	/**
	 * 获取报表周报开始日期
	 * @return
	 */
	public synchronized static String getWeekStart(Date nowDate) {
		String startTime = DateUtil.convertString(nowDate, "yyyy-MM-dd") + " 08:30:00";
		if (nowDate.getTime() > DateUtil.convertDate(startTime).getTime())
			return DateUtil.convertString(DateUtil.convertBeforeDayDate(nowDate, 6), "yyyy-MM-dd");

		return DateUtil.convertString(DateUtil.convertBeforeDayDate(nowDate, 7), "yyyy-MM-dd");
	}

	public static void main(String[] args){
		// System.out.println(getMonthFirstDay(DateUtil.convertDate("2024-03-14 08:30:00")));
		Date date = DateUtil.convertDate("2024-12-26 07:30:00", "yyyy-MM-dd HH:mm:ss");
		String startTime = ReportDateUtils.getMaterialMonthStartTime(date, true);
		String endTime = ReportDateUtils.getMaterialMonthEndTime(date, true);
		System.out.println(startTime + "\t" + endTime);
		date = DateUtil.convertDate("2024-01-23 07:30:00", "yyyy-MM-dd HH:mm:ss");
		startTime = ReportDateUtils.getMaterialMonthStartTime(date, true);
		endTime = ReportDateUtils.getMaterialMonthEndTime(date, true);
		System.out.println(startTime + "\t" + endTime);
		String day = getDay(date, "00:00:00");
		System.err.println(day);
	}

	/**
	 * 获取报表统计的第一天
	 * @return
	 */
	public synchronized static String getMonthFirstDay() {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		// 获取前月的第一天
		Calendar c1 = Calendar.getInstance();
		if(c1.get(Calendar.DAY_OF_MONTH) < 25){
			// 小于25号，设为上一月
			c1.set(Calendar.MONTH,c1.get(Calendar.MONTH) - 1);
		}else if(c1.get(Calendar.DAY_OF_MONTH) == 25){
			// 等于25号,是否8点半之前
			Calendar c2 = Calendar.getInstance();
			c2.set(Calendar.HOUR_OF_DAY,8);
			c2.set(Calendar.MINUTE,30);
			c2.set(Calendar.SECOND,0);
			if(c1.getTimeInMillis() < c2.getTimeInMillis()){
				// 8点半之前
				c1.set(Calendar.MONTH,c1.get(Calendar.MONTH) - 1);
			}
		}
		c1.set(Calendar.DAY_OF_MONTH, 25);
		return format.format(c1.getTime());
	}

	public synchronized static String getMonthFirstDay(Date date) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		// 获取前月的第一天
		Calendar c1 = Calendar.getInstance();
		c1.setTime(date);
		if (c1.get(Calendar.DAY_OF_MONTH) < 25) {
			// 小于25号，设为上一月
			c1.set(Calendar.MONTH, c1.get(Calendar.MONTH) - 1);
		} else if (c1.get(Calendar.DAY_OF_MONTH) == 25) {
			// 等于25号,是否8点半之前
			Calendar c2 = Calendar.getInstance();
			c2.setTime(date);
			c2.set(Calendar.HOUR_OF_DAY, 8);
			c2.set(Calendar.MINUTE, 30);
			c2.set(Calendar.SECOND, 0);
			if (c1.getTimeInMillis() < c2.getTimeInMillis()) {
				// 8点半之前
				c1.set(Calendar.MONTH, c1.get(Calendar.MONTH) - 1);
			}
		}
		c1.set(Calendar.DAY_OF_MONTH, 25);
		return format.format(c1.getTime());
	}

	/**
	 * 获取统计月的最后
	 * @return
	 */
	public synchronized static String getMonthEndDay() {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		// 获取前月的第一天
		Calendar c1 = Calendar.getInstance();
		if(c1.get(Calendar.DAY_OF_MONTH) < 25){
			// 小于25号,截止日就是当月25号
		}else if(c1.get(Calendar.DAY_OF_MONTH) == 25){
			// 等于25号,是否8点半之前
			Calendar c2 = Calendar.getInstance();
			c2.set(Calendar.HOUR_OF_DAY,8);
			c2.set(Calendar.MINUTE,30);
			c2.set(Calendar.SECOND,0);
			if(c1.getTimeInMillis() >= c2.getTimeInMillis()){
				// 8点半之前
				c1.set(Calendar.MONTH,c1.get(Calendar.MONTH) + 1);
			}
		}
		c1.set(Calendar.DAY_OF_MONTH, 25);
		return format.format(c1.getTime());
	}

	public synchronized static String getMonthEndDay(Date date) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		// 获取前月的第一天
		Calendar c1 = Calendar.getInstance();
		c1.setTime(date);
		if (c1.get(Calendar.DAY_OF_MONTH) < 25) {
			// 小于25号,截止日就是当月25号
		} else if (c1.get(Calendar.DAY_OF_MONTH) == 25) {
			// 等于25号,是否8点半之前
			Calendar c2 = Calendar.getInstance();
			c2.set(Calendar.HOUR_OF_DAY, 8);
			c2.set(Calendar.MINUTE, 30);
			c2.set(Calendar.SECOND, 0);
			if (c1.getTimeInMillis() >= c2.getTimeInMillis()) {
				// 8点半之前
				c1.set(Calendar.MONTH, c1.get(Calendar.MONTH) + 1);
			}
		}
		c1.set(Calendar.DAY_OF_MONTH, 25);
		return format.format(c1.getTime());
	}

	/**
	 * 获取报表统计的上月第一天
	 * @return
	 */
	public synchronized static String getLastMonthFirstDay(Date date) {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		// 获取前月的第一天
		Calendar c1 = Calendar.getInstance();
		c1.setTime(date);
		if(c1.get(Calendar.DAY_OF_MONTH) < 25){
			// 小于25号，设为上一月
			c1.set(Calendar.MONTH,c1.get(Calendar.MONTH) - 1);
		}else if(c1.get(Calendar.DAY_OF_MONTH) == 25){
			// 等于25号,是否8点半之前
			Calendar c2 = Calendar.getInstance();
			c2.set(Calendar.HOUR_OF_DAY,8);
			c2.set(Calendar.MINUTE,30);
			c2.set(Calendar.SECOND,0);
			if(c1.getTimeInMillis() < c2.getTimeInMillis()){
				// 8点半之前
				c1.set(Calendar.MONTH,c1.get(Calendar.MONTH) - 1);
			}
		}
		c1.set(Calendar.DAY_OF_MONTH, 25);
		return format.format(c1.getTime());
	}

	public synchronized static String getYearFirstDay() {
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
		// 当前年
		Calendar c1 = Calendar.getInstance();
		// 设置作为跨度的月日时分秒
		Calendar c2 = Calendar.getInstance();
		c2.set(Calendar.MONTH,11);
		c2.set(Calendar.DAY_OF_MONTH,25);
		c2.set(Calendar.HOUR_OF_DAY,8);
		c2.set(Calendar.MINUTE,30);
		c2.set(Calendar.SECOND,00);
		if(c1.getTimeInMillis() <= c2.getTimeInMillis()){
			// 小于时间跨度，年减1
			c1.set(Calendar.YEAR,c1.get(Calendar.YEAR) - 1);
			c1.set(Calendar.MONTH,11);
			c1.set(Calendar.DAY_OF_MONTH,25);
		}
		return format.format(c1.getTime());
	}



	/**
	 * 根据时间获取年报月份 格式yyyy-MM
	 * @param date 传入日期
	 * @return
	 */
	public synchronized static String getYearReportMonth(String date) {
		if (StringUtils.isNull(date) || date.length() < 8)
			return null;

		String day = date.substring(8);
		Integer num = StringUtils.convertInteger(day);
		if (num > 24) {
			date = DateUtil.getMonthNextFirstDay(DateUtil.convertDate(date, new SimpleDateFormat("yyyy-MM-dd")));
		}

		return date.substring(0, 7);
	}

	/**
	 * 获取报表统计中月报的起始时间
	 * @return
	 */
	public static synchronized String getMonthReportStartTime(){
		String today = DateUtil.convertString(new Date(),"yyyy-MM-dd");
		String startTime;
		if (today.equals(getMonthFirstDay())) {
			// 如果当天为跨域日，则月要减1
			Calendar c1 = Calendar.getInstance();
			c1.set(Calendar.MONTH,c1.get(Calendar.MONTH) - 1);
			startTime = DateUtil.convertString(c1.getTime(),"yyyy-MM-dd");
		} else {
			// 如果不为跨域日，则表示从当月第一天开算
			startTime = ReportDateUtils.getMonthFirstDay();
		}
		startTime += " 08:30:00";
		return  startTime;
	}

	/**
	 * 获取报表统计中月报的起始时间
	 * @return
	 */
	public static synchronized String getMonthReportStartTime(Date nowDate){
		String monthFirstDay = getMonthFirstDay(nowDate);
		monthFirstDay += " 08:30:00";
		return monthFirstDay;
	}

	/**
	 * 获取报表统计中月报的截止时间
	 * @return
	 */
	public static synchronized String getMonthReportEndTime(){
		String endTime = getMonthReportEndTime(new Date());
		return  endTime;
	}

	public static synchronized String getMonthReportEndTime(Date date) {
		// 获取前月的第一天
		Calendar c1 = Calendar.getInstance();
		c1.setTime(date);
		int day = c1.get(Calendar.DAY_OF_MONTH);
		if (day == 25) {
			// 等于25号,是否8点半之前
			Calendar c2 = Calendar.getInstance();
			c2.setTime(date);
			c2.set(Calendar.HOUR_OF_DAY, 8);
			c2.set(Calendar.MINUTE, 30);
			c2.set(Calendar.SECOND, 0);
			if (c1.getTimeInMillis() < c2.getTimeInMillis()) {
				// 8点半之前,为上个月
				c1.set(Calendar.MONTH, c1.get(Calendar.MONTH) - 1);
			} else {
				//	8点半之后,为下个月
				c1.set(Calendar.MONTH, c1.get(Calendar.MONTH) + 1);
			}
		} else if (day > 25) {
			//	直接将月设置成下一个
			c1.set(Calendar.MONTH, c1.get(Calendar.MONTH) + 1);
		}
		c1.set(Calendar.DAY_OF_MONTH, 25);
		c1.set(Calendar.HOUR_OF_DAY, 8);
		c1.set(Calendar.MINUTE, 30);
		c1.set(Calendar.SECOND, 0);
		Date time = c1.getTime();
		String endTime = DateUtil.convertString(time, "yyyy-MM-dd 08:30:00");
		return endTime;
	}

	/**
	 *  获取当月第一天到当天的数据
	 */
	public static List<String> getCurrentMonthDateList() {
		List<String> dateList = new ArrayList<>();
		// 获取当月第一天
		String monthFirstDay = getMonthReportStartTime();
		Date startDate = DateUtil.convertDate(monthFirstDay);
		Date currentDate = new Date();
		Calendar c = Calendar.getInstance();
		while (startDate.before(currentDate) || startDate.equals(currentDate)){
			// 格式化并设到列表
			String s = DateUtil.convertString(startDate, "yyyy-MM-dd");
			dateList.add(s);
			c.setTime(startDate);
			c.set(Calendar.DAY_OF_YEAR,c.get(Calendar.DAY_OF_YEAR) + 1);
			startDate = c.getTime();
		}
		return dateList;
	}

	/**
	 * 获取当前统计月份
	 * @return
	 */
	public static String getMonth(){
		String month = getMonth(null);
		return month;
	}

	public static String getMonth(Date date) {
		Calendar cla = Calendar.getInstance();
		if (date != null) {
			cla.setTime(date);
		}
		int day = cla.get(Calendar.DAY_OF_MONTH);
		int month;
		if(day > 25){
			// 下个月
			month = cla.get(Calendar.MONTH) + 2;
		}else if(day == 25){
			Calendar c2 = Calendar.getInstance();
			c2.set(Calendar.HOUR_OF_DAY,8);
			c2.set(Calendar.MINUTE,30);
			c2.set(Calendar.SECOND,0);
			if(c2.getTimeInMillis() >= cla.getTimeInMillis()){
				// 当月
				month = cla.get(Calendar.MONTH) + 1;
			}else {
				// 下月
				month = cla.get(Calendar.MONTH) + 2;
			}
		}else  {
			// 当月
			month = cla.get(Calendar.MONTH) + 1;
		}
		int year = cla.get(Calendar.YEAR);
		String monthStr;
		if(month < 10){
			monthStr = "0" + month;
		}else {
			monthStr = "" + month;
		}
		String r = year + "-" + monthStr;
		return r;
	}

	/**
	 * 获取材料报表月报开始时间
	 *
	 * @param nowDate
	 * @param isTime  是否加时分秒 false：不加，true加
	 * @return
	 */
	public synchronized static String getMaterialMonthStartTime(Date nowDate, Boolean isTime) {
		if (nowDate == null)
			nowDate = new Date();
		if (isTime == null)
			isTime = false;

		String today = DateUtil.convertString(nowDate, "yyyy-MM-dd");
		Date flagDate = DateUtil.convertDate(today + " 08:30:00");//比较时间
		String[] times = today.split("-");
		Integer year = StringUtils.convertInteger(times[0]);
		Integer month = StringUtils.convertInteger(times[1]);
		Integer day = StringUtils.convertInteger(times[2]);
		String flagTime = "";
		if (isTime)
			flagTime = " 08:30:00";
//		if (month == 1) {//如果是1月
//			if (day < 25) {
//
//				return year + "-01-01" + flagTime;
//			}
//			if (day == 25) {
//				if (nowDate.getTime() < flagDate.getTime())
//					return year + "-01-01" + flagTime;
//				else
//					return year + "-01-25" + flagTime;
//			} else {
//				return year + "-01-25" + flagTime;
//			}
//		} else {
			if (isTime)
				return getMonthFirstDay(nowDate) + flagTime;
			else
				return getMonthFirstDay(nowDate);
//		}
	}

	/**
	 * 获取材料报表月报结算时间
	 *
	 * @param nowDate
	 * @param isTime  是否加时分秒 false：不加，true加
	 * @return
	 */
	public synchronized static String getMaterialMonthEndTime(Date nowDate, Boolean isTime) {
		if (nowDate == null)
			nowDate = new Date();
		if (isTime == null)
			isTime = false;

		String today = DateUtil.convertString(nowDate, "yyyy-MM-dd");
		Date flagDate = DateUtil.convertDate(today + " 08:30:00");//比较时间
		String[] times = today.split("-");
		Integer year = StringUtils.convertInteger(times[0]);
		Integer month = StringUtils.convertInteger(times[1]);
		Integer day = StringUtils.convertInteger(times[2]);
		String flagTime = "";
//		if (isTime)
//			flagTime = " 08:30:00";
//		if (month == 12) {//如果是12月
//			return year + "-12-31" + flagTime;
//		} else {
//			if (month == 11) {
//				if (day >= 25 && nowDate.getTime() > flagDate.getTime()) {
//					return year + "-12-31" + flagTime;
//				}
//			}
			return getMonthEndTime(nowDate, isTime);
//		}
	}

	/**
	 * 获取材料报表月报结算时间
	 *
	 * @param nowDate
	 * @param isTime  是否加时分秒 false：不加，true加
	 * @return
	 */
	public synchronized static String getMonthEndTime(Date nowDate, Boolean isTime) {
		if (nowDate == null)
			nowDate = new Date();
		if (isTime == null)
			isTime = false;

		String today = DateUtil.convertString(nowDate, "yyyy-MM-dd");
		Date flagDate = DateUtil.convertDate(today + " 08:30:00");//比较时间
		String[] times = today.split("-");
//		Integer year = StringUtils.convertInteger(times[0]);
//		Integer month = StringUtils.convertInteger(times[1]);
		Integer day = StringUtils.convertInteger(times[2]);
		String flagTime = "";
		if (isTime)
			flagTime = " 08:30:00";
		if (day < 25) {//如果是小于25号
			return DateUtil.convertString(nowDate, "yyyy-MM") + "-25" + flagTime;
		}
		if (day == 25) {
			if (nowDate.getTime() < flagDate.getTime()) {
				return DateUtil.convertString(nowDate, "yyyy-MM") + "-25" + flagTime;
			} else {
				return DateUtil.convertString(DateUtil.convertBeforeMonthDate(nowDate, -1), "yyyy-MM") + "-25" + flagTime;
			}
		} else {
			return DateUtil.convertString(DateUtil.convertBeforeMonthDate(nowDate, -1), "yyyy-MM") + "-25" + flagTime;
		}
	}

	/**
	 * 根据date时间获取报表类的日期
	 *
	 * @param date
	 * @return
	 */
	public synchronized static String getDay(Date date) {
		return getDay(date, null);
	}

	/**
	 * 获取统计的日期
	 *
	 * @param dataDate 具体时间点
	 * @param billTime 时间点,格式为HH:mm:ss
	 * @return
	 */
	public synchronized static String getDay(Date dataDate, String billTime) {
		if (dataDate == null) {
			return null;
		}
		if (!StringUtils.validatorDate(billTime, DateUtil.TIME_ABBR_FORMATTER)) {
			//	默认时间
			billTime = "08:30:00";
		}
		String[] split = billTime.split(":");
		Calendar c = Calendar.getInstance();
		//	设置时间
		c.setTime(dataDate);
		//	数据时间
		long dataMill = c.getTimeInMillis();
		//	小时
		c.set(Calendar.HOUR_OF_DAY, Integer.valueOf(split[0]));
		//	分钟
		c.set(Calendar.MINUTE, Integer.valueOf(split[1]));
		//	秒
		c.set(Calendar.SECOND, Integer.valueOf(split[2]));
		//	标准时间
		long standardMill = c.getTimeInMillis();
		if (dataMill < standardMill) {
			//	小于8点半的算头一天
			c.set(Calendar.DAY_OF_MONTH, c.get(Calendar.DAY_OF_MONTH) - 1);
		}
		Date time = c.getTime();
		String s = DateUtil.convertString(time, DateUtil.DATE_ABBR_FORMATTER);
		return s;
	}

	/**
	 * 获取最近的25号时间
	 * @param date
	 * @return
	 */
	public static LocalDate findLast25th(LocalDate date) {

		// 尝试将当前日期设置为当月的25号
		LocalDate result = LocalDate.of(date.getYear(), date.getMonth(), 25);

		// 如果尝试设置的日期比当前日期还要未来，说明25号在下个月，
		// 那么我们需要减去一个月得到上个月的25号
		if (result.isAfter(date)) {
			return result.minusMonths(1);
		}
		// 否则，直接返回25号
		return result;
	}

}
